﻿using System;
using System.IO;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Reflection;
using System.Threading;

namespace WebServer.Modules
{
	/// <summary>
	/// WebServer Configuration
	/// </summary>
	[CoreModule("Listener", typeof(Listener), CoreModulePriority.Highest)]
	public static class Listener
	{
		private static List<string> _Hosts = new List<string>();
		/// <summary>
		/// Remote Hosts Registry, storing all Listener Host entries
		/// </summary>
		public static List<string> Hosts { get { return _Hosts; } }

		/// <summary>
		/// Initializes the Listener Hosts list.
		/// </summary>
		private static void Start()
		{
			Add("+");

			Events.CoreInitialized += new CoreInitializedEventHandler(Events_CoreInitialized);
			Events.CoreClosed += new CoreClosedEventHandler(Events_CoreClosed);
		}

		private static void Events_CoreInitialized()
		{
			Load();
		}

		private static void Events_CoreClosed()
		{
			Save();
		}

		/// <summary>
		/// Register a Listener Host that requires a Port. Hosts must be registered before the Core is initialized, if a host is added while the Core is running, the Core must be restarted for the changes to take effect.
		/// </summary>
		/// <param name="host">Host-Name, IPv4, IPv6 or '+' for all available IP Addresses</param>
		/// <param name="port">Listener Port, this port should be public and configured to accept incomming connections</param>
		public static void Add(string host, int port)
		{
			string hostName = String.Format("http://{0}:{1}/", host, port);

			if (!_Hosts.Contains(hostName))
			{ _Hosts.Add(hostName); }
		}

		/// <summary>
		/// Register a Listener Host that does not require a Port. Hosts must be registered before the Core is initialized, if a host is added while the Core is running, the Core must be restarted for the changes to take effect.
		/// </summary>
		/// <param name="host">Host-Name, IPv4, IPv6 or '+' for all available IP Addresses</param>
		public static void Add(string host)
		{
			string hostName = String.Format("http://{0}/", host);

			if (!_Hosts.Contains(hostName))
			{ _Hosts.Add(hostName); }
		}

		private static void Save()
		{
			FileInfo info = IOUtility.EnsureFile(Core.BaseDirectory + "\\" + Config.SystemName + "\\Cache\\listener.cache", true);

			using (StreamWriter writer = new StreamWriter(info.Open(FileMode.Truncate)))
			{
				foreach (string host in _Hosts)
				{
					writer.WriteLine(host);
				}

				writer.Close();
			}
		}

		private static void Load()
		{
			FileInfo info = IOUtility.EnsureFile(Core.BaseDirectory + "\\" + Config.SystemName + "\\Cache\\listener.cache", false);

			using (StreamReader reader = new StreamReader(info.OpenRead()))
			{
				string[] lines = File.ReadAllLines(info.FullName, Encoding.Default);

				foreach (string line in lines)
				{
					if (String.IsNullOrEmpty(line))
						continue;

					if (!_Hosts.Contains(line))
					{ _Hosts.Add(line); }
				}

				reader.Close();
			}
		}
	}
}
